package sk.naive.talker.command;

import sk.naive.talker.*;
import sk.naive.talker.message.DefaultMessageFactory;
import sk.naive.talker.props.PropertyStoreException;
import sk.naive.talker.persistence.*;

import sk.naive.talker.util.Utils;

import java.rmi.RemoteException;
import java.util.regex.*;
import java.util.logging.Level;

/**
 * ThingAdmin.
 *
 * @author <a href="mailto:sue@naive.deepblue.sk">Sue</a>
 * @version $Revision: 1.4 $ $Date: 2005/03/03 20:59:07 $
 */
public class ThingAdmin extends AbstractCommand {
	private static final String TCMD_CREATE = "create";
//	private static final String LCMD_DESC = "description";
	private static final String TCMD_DESTROY = "destroy";
	private static final String TCMD_LIST = "list";
//	private static final String LCMD_RENAME = "rename";

//	public static final String PERM_THING_ADMIN = "thingAdmin";

	private static Pattern pattern = Pattern.compile("(\\S+) +(\\S+)(?: +(\\S+))?");

	public void exec()
		throws CommandException,
		RemoteException
	{
		Utils.checkPermission(user, Consts.PERM_SUPERUSER);

		if (params == null) {
			sendMisusageWarning();
			return;
		}

		ThingFinder tf = commandDispatcher.thingFinder();

		String[] sa = Utils.splitWords(params, 2);
		if (TCMD_LIST.startsWith(sa[0])) {
			StringBuilder sb = new StringBuilder();
			sb.append(getString("thingAdmin.list.head", user.getProperties()));

			if (sa.length > 1) {
				String type = Utils.findFirstInCollection(sa[1], tf.thingTypes(), true);
				if (type == null) {
					sendHelper().sendMessage(user, "thingAdmin.typeNotFound");
					return;
				}
				for (Thing thing : tf.things(type)) {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL, thing.getType());
					ctxSet(DefaultMessageFactory.CTXKEY_VAL + "1", thing.getName());
					sb.append(getString("thingAdmin.list.item", user.getProperties()));
				}
			} else {
				for (String type : tf.thingTypes()) {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL, type);
					ctxSet(DefaultMessageFactory.CTXKEY_VAL + "1", tf.things(type).size());
					sb.append(getString("thingAdmin.list.itemCount", user.getProperties()));
				}
			}

			sb.append(getString("thingAdmin.list.tail", user.getProperties()));
			user.send(sb.toString());
			return;
		}

		Matcher matcher = pattern.matcher(params);
		if (!matcher.matches()) {
			sendMisusageWarning();
			return;
		}

		String thingType = Utils.findFirstInCollection(matcher.group(1), tf.thingTypes(), true);
		if (thingType == null) {
			sendHelper().sendMessage(user, "thingAdmin.typeNotFound");
			return;
		}
		String thingCmd = matcher.group(2).toLowerCase();
		String thingName = matcher.group(3);
		try {
			ctxSet(DefaultMessageFactory.CTXKEY_VAL, thingType);
			if (TCMD_CREATE.startsWith(thingCmd)) {
				if (thingName == null) {
					sendHelper().sendMessage(user, "thingAdmin.nameIsEmpty");
					return;
				}
				Thing thing = tf.createThing(thingType, thingName);
				if (thing != null) {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL + "1", thing.getName());
					sendHelper().sendMessage(user, "thingAdmin.created");
					logger().log(Level.INFO, "User {0} created thing {1}.", new Object[] {user.getLogin(), thing.getName()});
				} else {
					ctxSet(DefaultMessageFactory.CTXKEY_VAL + "1", thingName);
					sendHelper().sendMessage(user, "thingAdmin.alreadyExists");
				}
			} else if (TCMD_DESTROY.startsWith(thingCmd)) {
				Thing thing = tf.findThingByTypeAndName(thingType, thingName);
				if (thing == null) {
					noSuchThingWarning(user, thingType);
					return;
				}
				tf.destroy(thing);
				ctxSet(DefaultMessageFactory.CTXKEY_VAL + "1", thing.getName());
				sendHelper().sendMessage(user, "thingAdmin.destroyed");
				logger().log(Level.INFO, "User {0} destroyed thing {1}.", new Object[] {user.getLogin(), thing.getName()});
	/*
			} else if (LCMD_RENAME.startsWith(thingCmd)) {
				if (matcher.group(4) == null || matcher.group(3) != null) {
					sendMisusageWarning();
					return;
				}
				Thing thing = tf.findThingByName(thingName);
				if (thing == null) {
					noSuchThingWarning(user, thingName);
					return;
				}
				String oldName = thing.getName();
				ctxSet(DefaultMessageFactory.CTXKEY_VAL, oldName);
				thing.set(Thing.LPROP_NAME, matcher.group(4));
				ctxSet(DefaultMessageFactory.CTXKEY_VAL + 1, thing.getName());
				sendMessage(user, "thingAdmin.renamed");
				logger().log(Level.INFO, "User {0} renamed thing {1} to {2}.", new Object[] {user.getLogin(), oldName, thing.getName()});
			} else if (LCMD_DESC.startsWith(thingCmd)) {
				Thing thing = lf.findThingByName(thingName);
				if (thing == null) {
					noSuchThingWarning(user, thingName);
					return;
				}
				ctxSet(DefaultMessageFactory.CTXKEY_VAL, thing.getName());
				new EditorHelper(this, thing).start(thing);
	*/
			} else {
				sendMisusageWarning();
			}
		} catch (PersistenceException e) {
			throw new CommandException(e);
		} catch (PropertyStoreException e) {
			throw new CommandException(e);
		}
	}

	private void noSuchThingWarning(User u, String thingName) throws RemoteException {
		ctxSet(DefaultMessageFactory.CTXKEY_VAL, thingName);
		sendHelper().sendMessage(u, "thingAdmin.noSuchThing");
	}
}